package per.hongze.javatest.action;

import com.mysql.jdbc.Driver;

import java.sql.*;

/**
* @description: 测试jdbc使用
* @author YiDan
* @date 2022/6/26 23:25
* @version 1.0
*/

public class MysqlUse {

    /**
     * <p>
     * 第一步：注册驱动
     * 通过创建驱动对象告知JDBC，我们即将连接哪个厂商的数据库
     * <p/>
     *
     * @param
     * @return void
     * @Date 2020/6/7 11:23
     */
    public static void registerDriver() {
        try {
            //注册驱动（new com.mysql.jdbc.Driver()也是可以的）
            Driver driver = new com.mysql.jdbc.Driver();
            DriverManager.registerDriver(driver);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * <p>
     * 第二步：获取数据库连接
     * 注意：Connection连接对象不能随意创建，最后使用完需要手动关闭
     * <p/>
     *
     * @param
     * @return java.sql.Connection
     * @Date 2020/6/7 11:24
     */
    public static Connection getConnection() {
        try {
            //注册驱动
            registerDriver();

            //获取数据库连接
            //url统一资源定位
            String url = "jdbc:mysql://127.0.0.1:3306/system";
            String userName = "root";
            String passWord = "123456";
            Connection connection = DriverManager.getConnection(url, userName, passWord);

            //打印Connection对象的内存地址：com.mysql.cj.jdbc.ConnectionImpl@69d9c55
            System.out.println("MySql数据库，对java.sql.Connection接口的实现类的完整类名：" + connection);
            return connection;
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * <p>
     * 第三步：获取数据库操作对象
     * 拿到Statement数据库操作对象，就可以执行sql语句
     * <p/>
     *
     * @param
     * @return java.sql.Statement
     * @Date 2020/6/7 11:42
     */
    public static Statement getStatement() {
        try {
            //获取数据库连接
            Connection connection = getConnection();

            //获取数据库操作对象
            //一个连接对象，可以获取多个数据库操作对象
            Statement statementOne = connection.createStatement();
            //打印Statement对象的内存地址：com.mysql.cj.jdbc.StatementImpl@23f7d05d
            System.out.println("MySql数据库，对java.sql.Statement接口的实现类的完整类名：" + statementOne);

            //打印Statement对象的内存地址：com.mysql.cj.jdbc.StatementImpl@1e730495
            //Statement statementTwo = connection.createStatement();
            //System.out.println("MySql数据库，对java.sql.Statement接口的实现类的完整类名：" + statementTwo);

            return statementOne;
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * <p>
     * 第四步：执行SQL语句
     * <p/>
     *
     * @param
     * @return void
     * @Date 2020/6/7 11:51
     */
    public static void executeSql() {
        try {
            //获取数据库操作对象
            Statement statement = getStatement();
            //执行SQL语句
            //注意：jdbc中，sql语句不需要以分好;结尾，当然，你写了也不会报错

            //定义DDL语句，这里可以创建表，但是，一般不这么玩，jdbc中，通常是写DML语句和DQL语句
            /*String sql = "CREATE TABLE `user` (\n" +
                    "  `id` bigint(32) NOT NULL auto_increment,\n" +
                    "  `userName` varchar(20) DEFAULT NULL COMMENT '用户名称',\n" +
                    "  `email` varchar(128) DEFAULT NULL COMMENT '邮箱|登录帐号',\n" +
                    "  `passWord` varchar(64) DEFAULT NULL COMMENT '密码',\n" +
                    "  `createTime` datetime DEFAULT NULL COMMENT '创建时间',\n" +
                    "  `lastLoginTime` datetime DEFAULT NULL COMMENT '最后登录时间',\n" +
                    "  `status` bigint(1) DEFAULT '1' COMMENT '1:有效，0:禁止登录',\n" +
                    "  PRIMARY KEY (`id`)\n" +
                    ") ENGINE=InnoDB DEFAULT CHARSET=utf8";*/

            //定义DML语句
            String sql = "insert into `user`(`userName`,`passWord`,`status`) values('lisi','123','1')";

            //将sql语句发送给数据库管理系统，数据库管理系统（DBMS）会编译并执行该sql语句
            int count = statement.executeUpdate(sql);

            System.out.println(count);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * <p>
     * 第五步：处理查询结果集
     * <p/>
     *
     * @param
     * @return void
     * @Date 2020/6/7 12:48
     */
    public static void dealResultSet() {
        try {
            //获取数据库操作对象
            Statement statement = getStatement();
            //定义DQL语句
            String sql = "select * from `user` where userName = 'lisi'";

            //将sql语句发送给数据库管理系统，数据库管理系统（DBMS）会编译并执行该sql语句，把查询结果集放到ResultSet结果集对象中
            ResultSet resultSet = statement.executeQuery(sql);

            //处理查询结果集，一个Statement可以得出多个ResultSet
            //resultSet.next()方法作用：if the new current row is valid, return true. if there are no more rows, return false
            //将光标向前移动一行，如果指向当前行有记录，则返回true，若指向当前行无记录，返回false
            while (resultSet.next()) {
                //获取当前光标指向行中的数据，有三种方式：

                //第一种方式：根据字段下标获取，不管数据库表中的字段是什么类型，都以字符串方式取出
                //JDBC所有下标都是以1开始
                String id1 = resultSet.getString(1);
                String userName1 = resultSet.getString(2);
                String status1 = resultSet.getString(7);
                System.out.println("id1:" + id1 + "，用户名1：" + userName1 + "，有效状态1：" + status1);

                //第二种方式：通过结果集中字段名称获取数据，该方式的程序更加健壮，建议使用
                String id2 = resultSet.getString("id");
                String userName2 = resultSet.getString("userName");
                String status2 = resultSet.getString("status");
                System.out.println("id2:" + id2 + "，用户名2：" + userName2 + "，有效状态2：" + status2);

                //第三种方式：通过特定类型获取数据，该方式，明确知道字段的类型，可以节省类型转换花费的性能，该方式的程序更加健壮，性能更高，推荐使用
                int id3 = resultSet.getInt("id");
                String userName3 = resultSet.getString("userName");
                String status3 = resultSet.getString("status");
                System.out.println("id3:" + id3 + "，用户名3：" + userName3 + "，有效状态3：" + status3);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }



    public static void main(String[] args) throws Exception {

    }
}
